/*  recognizer.cpp
    
    Recognizer class for ensuring that parsed Lexemes
    are compatible with a given grammar.

    Nicholas Green
    Recognizer
*/
#include "recognizer.h"
#include "lex.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>

Recognizer::Recognizer(FILE* file)
{
  currentLexeme = NULL;
  m_Lex = new Lex(file);
}

Recognizer::~Recognizer()
{
  printf("Destructing...");
  if(currentLexeme != NULL)
    delete(currentLexeme);
  if(m_Lex != NULL)
    delete(m_Lex);
  printf("Done!\n");
}


bool Recognizer::check(const char* type)
{
  if(currentLexeme == NULL)
    return false;
  return strcmp(currentLexeme->getTVal(), type) ? false : true;

}

void Recognizer::advance()
{
  delete(currentLexeme);
  currentLexeme = NULL;
  //currentLexeme = new Lexeme(m_Lex->lex());
  currentLexeme = m_Lex->lex();
}

Lexeme* Recognizer::match(const char* type)
{
  int l = currentLexeme->getLine();
  Lexeme* m = NULL;
  if(strcmp(currentLexeme->tVal,ID) == 0)
    m = new Lexeme(ID, currentLexeme->sVal,l);
  else if(strcmp(currentLexeme->tVal,INTEGER) == 0)
    m = new Lexeme(INTEGER, currentLexeme->iVal, l);
  else if(strcmp(currentLexeme->tVal,STRING) == 0)
  {
    std::string s = currentLexeme->sVal;
    m =  new Lexeme(STRING, s, l);
  }
  else
    m = new Lexeme(type, l);
  matchNoAdvance(type); 
  advance();
  //return new Lexeme(type, l);
  return m;
}

void Recognizer::matchNoAdvance(const char* type)
{
  try
  {
    if (!check(type))
      throw exit_exception(1,currentLexeme->getTVal(), currentLexeme->getSVal().c_str(),type, currentLexeme->getLine());
  }
  catch(exit_exception& e)
  {
    exit(e.m_code);
  }
}
